package net.gazhi.delonix.core.thread;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import net.gazhi.delonix.core.util.IPUtils;

/**
 * * 线程上下文重置过滤器<br>
 * <br>
 * 先清空线程上下文，然后把 application context 和 loginUser 缓存到当前线程<br>
 * 请求处理结束后，再次清空上下文，以释放内存资源和防止不同请求的数据污染
 * 
 * @author jeffreylin@gazhi.net
 *
 */
public class ResetThreadContextFilter extends OncePerRequestFilter {

	/**
	 * 从 Request 中提取终端 IP
	 * 
	 * @param request
	 * @return 常规字符串形式的 IP
	 */
	public static String getClientIpStr(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("PRoxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	/**
	 * 请了和设置 http 请求处理线程的缓存
	 */
	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
		try {
			ThreadContext.clear();
			long clientIp = IPUtils.parse(getClientIpStr(request));
			ThreadContext.setClientIp(clientIp);
			ThreadContext.setAppContext(WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()));
			filterChain.doFilter(request, response);
		} finally {
			ThreadContext.clear();
		}
	}

}